import os
import time
import traceback
from fastapi import FastAPI, Request
from fastapi.responses import FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles

from starlette.middleware.cors import CORSMiddleware

from api.routers import api_router

from api.settings import settings


def create_application() -> FastAPI:
    # 等待其他组件启动完成
    time.sleep(3)
    application = FastAPI()
    application.include_router(api_router, prefix="/api")
    register_middleware(application)
    register_static(application)
    register_event(application)
    return application


def register_middleware(application):
    if settings.BACKEND_CORS_ORIGINS:
        application.add_middleware(
            CORSMiddleware,
            allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
            allow_credentials=True,
            allow_methods=["*"],
            allow_headers=["*"],
        )


def register_static(app):
    # 挂载静态文件
    backend = os.path.dirname(os.path.abspath(__file__))
    app.mount("/static", StaticFiles(directory=os.path.join(backend, "static")))

    @app.get("/")
    async def read_index():
        return FileResponse(os.path.join(backend, "static", "index.html"))

    @app.exception_handler(404)
    async def not_found(request: Request, exc):
        accept = request.headers.get("accept")
        if not accept:
            return JSONResponse(content={"error": "Not found"}, status_code=exc.status_code)
        if exc.status_code == 404 and "text/html" in accept:
            return JSONResponse(content={"error": "404 Not found"}, status_code=exc.status_code)
        else:
            return JSONResponse(content={"error": "Other error"}, status_code=exc.status_code)


async def register_elasticsearch():
    pass


def register_event(app):
    @app.on_event("startup")
    async def startup_event():
        try:
            await register_elasticsearch()
        except Exception as e:
            traceback.print_exc()

    @app.on_event("shutdown")
    async def shutdown_event():
        try:
            # from api.utils.elastic import es
            # await es.close()
            pass
        except Exception as e:
            # 直观的打印错误信息
            traceback.print_exc()
